// request模块 （为api模块服务）:
// 1.AXIOS实例 2.请求拦截器 3.响应拦截器
import store from '@/store'
import router from '@/router'
// 导入axios
import axios from 'axios'
import { Message } from 'element-ui'
import { getToken } from './auth'
// create() -> 创建axios新实例 
// 1.baseURL 接口基地址
// 2.timeout 请求超时时间 如果还没有返回 取消掉

// service实例 = axios + 额外的配置 【更加强大定制化的axios】
// create方法是可以执行多次的 多个实例对应不同的配置项
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_URL,
  timeout: 5000 // request timeout 超时时间 超过了时间 如果还没返回 就取消掉
})

const service1 = axios.create({
  baseURL: 'xxx.com'
})

// axios的请求拦截器： 在请求正式发送之前 可以对请求参数做一些额外的定制
// 做什么？ request header 添加了token
service.interceptors.request.use(
  config => {
    //config 请求配置参数对象 可以在发送请求前操作请求参数
    // 不可丢失return
    // 在这个位置需要统一注入请求头
    // token存入请求头
    // token在vuex或在cookie里取都可以
    const token = getToken()//cookie中获取
    // const token = store.state.user.token// vuex中获取
    if(token){//若token存在 便把tokenz注入请求头中
      config.headers['Authorization'] = `Bearer ${token}`
      // 例如 const obj = {name: 'cp'}; obj['name']='cp'
      // []写法更加通用 内部支持变量 函数 三元表达式
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器：返回数据到客户端之前对返回值做一些处理
// ？token失效 接口 401 退出登录
// 成功回调和失败回调什么时候执行？ http码判断的200-300之间 成功 走第一个回调
// 成功回调和失败回调什么时候执行？ http 码判断的 200-300 成功 走第一个回调 不在这个之间走失败的回调
// 问题: 后端自己定义了一个标识当前接口成功失败的字段，叫做success(success:false 失败 success: true 成功)，而不是通过http状态码是否为2xx-3xx,来标识接口是否成功，
// 这和axios拦截器的成功和失败的判断依据是不一致的会导致一个严重的问题，如果接口已经错了，axios依旧走的是成功回调，会导致不抛出错误,静默通过
// 解决:以后端实际返回的判断字段为主 前端进行错误自行抛出
service.interceptors.response.use(
  // http 状态码 200-300码
  response => {
    // 这里axios 默认会把后端返回的数据存入一个自己包装的对象里面
    // 放到一个名称为data的属性上,如果你想简化她的使用 就可以直接return xx.data
    // 保证在组件中拿到的数据和后端返回的数据是一致的
    // 解构后端字段
    // data 接口数据
    // success 接口是否成功
    // message 接口提示文案
    const {data, message, success} = response.data
    if(success){
      // 接口成功-正常返回数据
      return data
    }else {
      // 提示用户
      Message.warning(message)
      // 接口失败-自行抛出错误
      return Promise.reject(message)
    }
    // return response.data
  },
  error => {
    console.dir(error);
    if(error.response.status === 401) {
      // 1.清空失效的数据
      store.commit('user/removeUerInfo')
      // 2.跳转到登录页
      router.push('/login')
    }
    return Promise.reject(error)
  }
)
// 默认导出service
export default service

/* 
service实例会和API接口魔魁啊形成一个1对多的关系，这个关系可以帮助我们统一管理所有接口
让每一个实例使用service实例的接口都自动有了token 都自动被我们响应式拦截器控制
*/